/*
*
 * Justin Swinney
 * CPE301_DA7.c
 * The goal of the assignment is to modify the above codes to do the following:
 * Write a C AVR program that will monitor the LM34/LM35 connected to an Analog pin
 * to display the temperature in C or F on the Nokia 5110 GLCD display.
 *
 */ 

#include <avr/io.h>
#define F_CPU 8000000UL
#include <E:\School\Spring 14'\DA7\DA7\DA7\letters.h>
#include <avr/io.h> 
#include <util/delay.h>  

unsigned char t_high; // variable to hold high temperature value
unsigned char t_low; // variable to hold low temperature value

//sets up analog to digital conversion
void A2D_init()
{	
	DDRC = 0x00; //initialize for outputs on port C
	ADCSRA = 0xDF; //128 division factor
	ADMUX = 0xC0; //AREF and ADC0 selected
	ADCSRA = (ADCSRA  | (1 << 6)); //start conversion
}

// SPI Interrupt Initialization/Transfer
void spi_int(unsigned char data)
{
	DDRB = 0x2C; //SS, MOSI, and SCK outputs
	SPCR = 0x62; //spi int en, master spi mode, Fosc/64
	PORTB = (PORTB & ~(1 << 2)); //sets SS pin low, receive incoming data
	SPDR = data; // initiate data transmission
	
	while(!(SPSR & (1<<SPIF)))
	PORTB = (PORTB | (1 << 2)); //sets SS pin high, stops receiving
}

// writes data/commands to lcd
void write (unsigned char data)
{
	if (data & 0x80) // param sent was data
	PORTD = (PORTD |(1<<2));// DC pin is high for data
	else //param sent was a command
	PORTD = (PORTD & ~(1<<2)); // D/C pin set to active low
	
	PORTD = (PORTD & ~(1<<1)); // SCE pin set to active low, enable
	spi_int(data); // data for transmission
	PORTD = (PORTD | (1<<1)); // SCE pin set to active high, disable
}

// looks in letters.h file, grabs character desired, converts hex to character
void convertLetter(unsigned char letter)
{
	for(int i=0; i < 5; i++) //each ascii letter is 5-bits long
	write(H2C[letter - 0x20][i]); // (0x20) offets to first printable char
	write(0x00); //prints a space
}

//function to parse through a string and print to the lcd
void writeString(char *characters)
{
	while (*characters) //steps through the string
	convertLetter(*characters++);          // send each character to convert
}

//function to position the starting cursor
void lcd_cursorPos(unsigned char x, unsigned char y)
{
	//function to position the starting cursor
	write(0x80 | x); //7th bit is 1, indicating command passed
	write(0x40 | y); //7th bit is 1, indicating command passed
}

void sendToLCD()
{
	int temp_low = ADCL; //grabs low temp data
	//int temp_high = ADCH; //grabs h temp data	
	int t_temp = temp_low;// temp variable
	int temp_conv = t_temp/200;   //after calibration, convert to useful value
	
	int d1 = (temp_conv%100)/10; //retrieve 10's place
	int d2 = temp_conv%10; //retrieve 1's place	
	
	lcd_cursorPos(1,1); //initialized LCD starting position
	convertLetter(0x54); //prints T
	convertLetter(0x54); //prints e
	convertLetter(0x54); //prints m
	convertLetter(0x54); //prints p
	convertLetter(0x54); //prints space
	convertLetter(0x54); //prints :
	convertLetter(0x54); //prints space

	write(d1); // print first number
	convertLetter(0x54); //prints space
	write(d2); // print second number
	convertLetter(0x54); //prints space
	
	//wanted to incorporate both ways of printing to lcd screen
	writeString(" degrees F "); //prints entire string
	_delay_ms(500);

}
   
void lcd_init()
{
   DDRD = 0x0E; //sets up given pins for output
   DDRB = 0x28; //sets up given pins for output
   PORTD = (PORTD & ~(1<<3)); // Low pulse, Reset display              
   PORTD = (PORTD | (1<<3)); // high pulse, disable reset
   
  write(0x21); // LCD extended commands
  write(0xBf); // set LCD Vop (contrast)
  write(0x04); // set temp coefficent
  write(0x14); // LCD bias mode 1:40
  write(0x20); // LCD basic commands
  write(0x0C); // LCD normal video
}

void clear()
{
	for(int i=0; i < 504; i++) //clears entire lcd
		write(0x00); //passes 0's indicating data passed
}

int main()
{
	A2D_init();	//Initialize A2D converter, load settings
	lcd_init(); //initialize LCD
	while(1)	//continue reading temperature forever
	{	
		sendToLCD();
		ADCSRA = 0xBF; //clear AD complete flag	
		clear();
	} 
	return 0;
	}

